From: Georges Basile Stavracas Neto Date: Wed, 2 Dec 2020 20:43:13 +0000 (-0300) Subject: iconGrid/iconGrid: Wait for icon sizes before running spring animation X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~616^2^2~703 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=b730875012cabc4cf4ffecb869266b8a76ea64cc;p=gnome-shell.git iconGrid/iconGrid: Wait for icon sizes before running spring animation To run the spring animation, IconGrid uses the transformed position and size of the icons. This works okay when IconGridLayout doesn't need to update the icon sizes, but looks bad when IconGridLayout selects a different icon size. Wait for the icon sizes to be recalculated, and the icons beallocated, before running the spring animation. If no icon size update is pending, run the spring animation directly. Part-of: --- diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js index 093815922..b7c8db593 100644 --- a/js/ui/iconGrid.js +++ b/js/ui/iconGrid.js @@ -391,6 +391,9 @@ var IconGridLayout = GObject.registerClass({ this._containerDestroyedId = 0; this._updateIconSizesLaterId = 0; + + this._resolveOnIdleId = 0; + this._iconSizeUpdateResolveCbs = []; } _findBestIconSize() { @@ -701,11 +704,28 @@ var IconGridLayout = GObject.registerClass({ return isRtl ? rowAlign * -1 : rowAlign; } + _runPostAllocation() { + if (this._iconSizeUpdateResolveCbs.length > 0 && + this._resolveOnIdleId === 0) { + this._resolveOnIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { + this._iconSizeUpdateResolveCbs.forEach(cb => cb()); + this._iconSizeUpdateResolveCbs = []; + this._resolveOnIdleId = 0; + return GLib.SOURCE_REMOVE; + }); + } + } + _onDestroy() { if (this._updateIconSizesLaterId >= 0) { Meta.later_remove(this._updateIconSizesLaterId); this._updateIconSizesLaterId = 0; } + + if (this._resolveOnIdleId > 0) { + GLib.source_remove(this._resolveOnIdleId); + delete this._resolveOnIdleId; + } } vfunc_set_container(container) { @@ -820,6 +840,8 @@ var IconGridLayout = GObject.registerClass({ }); this._pageSizeChanged = false; + + this._runPostAllocation(); } /** @@ -964,6 +986,14 @@ var IconGridLayout = GObject.registerClass({ return itemData.pageIndex; } + ensureIconSizeUpdated() { + if (this._updateIconSizesLaterId === 0) + return Promise.resolve(); + + return new Promise( + resolve => this._iconSizeUpdateResolveCbs.push(resolve)); + } + adaptToSize(pageWidth, pageHeight) { if (this._pageWidth === pageWidth && this._pageHeight === pageHeight) return; @@ -1617,7 +1647,7 @@ var IconGrid = GObject.registerClass({ this.layout_manager.adaptToSize(width, height); } - animateSpring(animationDirection, sourceActor) { + async animateSpring(animationDirection, sourceActor) { this._resetAnimationActors(); let actors = this._getChildrenToAnimate(); @@ -1626,6 +1656,8 @@ var IconGrid = GObject.registerClass({ return; } + await this.layout_manager.ensureIconSizeUpdated(); + let [sourceX, sourceY] = sourceActor.get_transformed_position(); let [sourceWidth, sourceHeight] = sourceActor.get_size(); // Get the center